use std::iter::Map;

// extern crate function_name;
use function_name::named;

pub fn bczd_6() {
  test17();
}

fn test1() {
  let f = |i: i32| {
    return i;
  };
  println!("{:?}", f(3));
  // println!("{:?}", f.call(1));
}

struct Closure {
  value: u32,
}

impl FnOnce<()> for Closure {
  type Output = u32;

  extern "rust-call" fn call_once(self, args: ()) -> Self::Output {
    println!("{}", module_path!());
    return self.value + 2;
  }
}

impl Fn<()> for Closure {
  extern "rust-call" fn call(&self, args: ()) -> Self::Output {
    println!("{}", module_path!());
    return self.value + 2;
  }
}

impl FnMut<()> for Closure {
  #[named]
  extern "rust-call" fn call_mut(&mut self, args: ()) -> Self::Output {
    println!("{}", function_name!());
    return self.value + 2;
  }
}

fn test2() {
  let mut c = Closure { value: 2 };
  c.call(());
  c.call_mut(());
  c.call_once(());
}

trait Any {
  fn any(&self, f: &(dyn Fn(u32) -> bool)) -> bool;
}

impl Any for Vec<u32> {
  fn any(&self, f: &(dyn Fn(u32) -> bool)) -> bool {
    for &elem in self.iter() {
      if f(elem) {
        return true;
      }
    }
    return false;
  }
}

fn test3() {
  let v = vec![1, 2, 3, 4, 5];
  let ret = v.any(&|value| {
    return value % 4 == 0;
  });
  println!("{}", ret);
}

fn sum(a: i32, b: i32) -> i32 {
  return a + b;
}

fn product(a: i32, b: i32) -> i32 {
  return a * b;
}

type MathOp = fn(i32, i32) -> i32;
fn math(op: &str, a: i32, b: i32) -> MathOp {
  // 书上示例是错误的 170页
  match op {
    "sum" => sum,
    _ => product,
  }
}

fn test4() {
  let (a, b) = (1, 2);
  let ret = math("sum", a, b);
}

fn counter(i: i32) -> Box<dyn Fn(i32) -> i32> {
  return Box::new(move |n: i32| return n + i);
}

fn test5() {
  let ret = counter(1);
  let ret2 = ret(3);
}

fn counter2(i: i32) -> impl Fn(i32) -> i32 {
  return Box::new(move |n: i32| return n + i);
}

fn test6() {
  let ret = counter(1);
  let ret2 = ret(4);
}

fn test7() {
  // 如何确定两个对象的类型相同？？？？
  let b1 = || {};
  let b2 = || {};
  let a = [b1, b2];
  // 和书上讲的不一样了呢？？？ 173页
}

fn test8() {
  fn call_internal<F: FnOnce()>(f: F) {
    return f();
  }
  let mut x = 0;
  let incr_x = || x += 1;
  call_internal(incr_x);
  // call_internal(incr_x);
}

fn test9() {
  fn call_internal<F: FnOnce()>(f: F) {
    f()
  }
  let mut x = 0;
  let incr_x = move || x += 1;
  call_internal(incr_x);
  call_internal(incr_x);
}
fn test10() {
  fn call_internal<F: FnOnce()>(f: F) {
    f()
  }
  let mut x = vec![];
  let incr_x = move || x.push(1);
  call_internal(incr_x);
  // call_internal(incr_x);
}
fn test11() {
  fn call_internal<F: Fn()>(f: F) {
    return f();
  }
  let x = 0;
  let incr_x = || println!("{}", x);
  call_internal(incr_x);
  // call_internal(incr_x);
}

fn test12() {
  let mut s: Vec<Box<dyn Fn()>> = vec![];
  s.push(Box::new(|| ()));
  s.push(Box::new(|| println!("1")));
}
fn test13() {
  let mut s = [|| (), || println!("2")];
  let sss = s.as_mut();
  sss[3] = || ();
}

fn test14() {
  // let  s: impl Fn() = ||();
}

fn test15() {
  // page 191
  trait DoSomewhere {
    fn do_some_where();
    fn do_th(&self);
  }
  impl DoSomewhere for String {
    fn do_some_where() {
      println!("do_some_where");
    }
    fn do_th(&self) {
      println!("do_th");
    }
  }

  String::do_some_where();
  let y = Box::new(String::new());
  y.do_th();

  impl DoSomewhere for i32 {
    fn do_some_where() {
      println!("do_some_where");
    }
    fn do_th(&self) {
      println!("do_th");
    }
  }

  let x = 10;
  x.do_th();
  let xx = Box::new(12i32);
  xx.do_th();
}

fn test16() {
  let mut c = 0;
  let mut v = Vec::new();
  v.push('a');
  v.push('b');
  v.push('c');
  for pair in v.into_iter().map(|letter| {
    c += 1;
    (letter, c)
  }) {
    println!("{:?}", pair);
  }
}

fn test17() {
  // 找定义的最好方式是调试
  // 其次是查看源码，现代语言花样百出，想要通过静态分析找到定义是不容易的，同时考察的是对语言的熟悉程度
  let s = [1, 2, 3];
  s.iter().any(|letter| return false);
}
